//
//  main.m
//  第一个OC类 - 类方法定义工具
//
//  Created by wenjim on 17/8/28.
//  Copyright © 2017年 WenJim. All rights reserved.
//

#import <Foundation/Foundation.h>

/*
 事物名称：iPhone
 属性  ： 颜色，型号，cpu，尺寸   ＝＝＝ 成员变量
 行为  ：打电话，发短信，上网     ＝＝＝ 成员方法
 
 C语言中函数分为声明和实现
 OC中定义一个类也分为声明和实现，以后在OC中定义类，就是写类的声明和实现
 */

typedef enum
{
    KIColorBlack, // 黑色
    KIColorWhith, // 白色
    KIColorgold   // 土豪金
}IColor;

// 类名后面的 :NSObject 是为了让我们的IPhone 类具备创建对象的能力
// 1. 编写类的声明
@interface IPhone : NSObject
{
    // 注意：默认情况下，OC对象中的属性是不能直接访问的
@public // 只要让类中的属性公开，以后就可以直接通过一个指向结构体的指针来操作对象中的属性
    float _model; // 型号
    int _cpu; // cpu
    double _size; // 尺寸
//    int _color; // 颜色 0代表黑色 1代表白色 2代表土豪金
    IColor _color;
}



// 注意：OC的方法，如果没有形参不需要写()，而是直接写一个;
// 为什么OC中没有形参不需要写()呢？因为OC方法中的()有特殊用途，OC方法中的()用来括住数据类型的
// 没有返回值没有参数
-(void)about;

// 有返回值没有参数的，读取短信
-(char *)loadMessage;

// 有返回值有参数，打电话
- (int)call:(int)number;

// 有返回值并且有多个参数，发短信
- (int)sendMessage:(int)number :(char *)content;

// 为了提高我们的阅读性，OC方法允许我们给每个参数添加一个标签来说明当前参数的含义
// 注意：标签也是方法名的一部分
// 方法名是 sendMessageWithNumber:content:
- (int)sendMessageWithNumber:(int)number content:(char *)content;



// 计算器
// 如果不想每次使用方法都需要创建对象开辟存储空间
// 并且如果该方法中没有使用到属性(成员变量),那么你可以把这个方法定义为类方法
// 对象方法用对象调用 类方法用类调用
- (int)sumValue1:(int)value1 value2:(int)value2;

// 如何定义类方法，类方法的写法和对象方法一模一样，除了前面的 - 号不同以外，只需要将对象方法中的 - 号换成 + 号，那么就定义了一个类方法
+ (int)sumWithValue1:(int)value1 value2:(int)value2;
+ (void)test;

- (NSString *)ColorWithNumber:(IColor)number;
+ (NSString *)classColorWithNumber:(IColor)number;

@end

// 2.编写类的实现
// 以@implementation开头，以@end结尾，然后在class对应的地方写上声明的类的名称，必须和声明的类名一模一样
@implementation IPhone

// 行为的实现
-(void)about
{
    // 如果在对象方法中像访问该对象的属性，可以直接写上 _属性名称 即可
    
    //    NSLog(@"sum ＝ %i",[IPhone sumWithValue1:50 value2:50]);
   
//    IPhone * p = [IPhone new];
//    NSString * str = [p ColorWithNumber:2];
    
    NSString * str = [IPhone classColorWithNumber:2];
    
    NSLog(@"尺寸 = %f, cpu = %i, 型号 = %.f, 颜色 = %@\n",_size,_cpu,_model,str);
    
//    IPhone * p = [IPhone new];
//    NSLog(@"%s",[p loadMessage]);
}

// 工具方法，根据传入的整数返回对应的字符串
- (NSString *)ColorWithNumber:(IColor)number
{
    NSString * name;
    switch (number) {
        case 0:
        {
            name = @"黑色";
        }
            break;
        case 1:
        {
            name = @"白色";
        }
            break;
        case 2:
        {
            name = @"土豪金";
        }
            break;
            
        default:
        {
            name = @"改装机";
        }
            break;
    }
    
    return name;
}

+ (NSString *)classColorWithNumber:(IColor)number
{
    NSString * name;
    switch (number) {
        case 0:
        {
            name = @"黑色";
        }
            break;
        case 1:
        {
            name = @"白色";
        }
            break;
        case 2:
        {
            name = @"土豪金";
        }
            break;
            
        default:
        {
            name = @"改装机";
        }
            break;
    }
    return name;
}

// 读短信
-(char *)loadMessage
{
    return "Hello,What will you eat today?";
}

// 打电话
- (int)call:(int)number
{
    
    NSLog(@"拨打%i",number);
    
    return 2;
}

// 发短信
- (int)sendMessage:(int)number :(char *)content
{
    NSLog(@"发送短信给%i,内容是%s",number,content);
    return 1;
}

- (int)sendMessageWithNumber:(int)number content:(char *)content
{
    NSLog(@"发送短信给%i,内容是%s",number,content);
    return 1;
}

- (int)sumValue1:(int)value1 value2:(int)value2
{
    return value1 + value2;
}


// 注意：如果声明的是对象方法，那么就必须实现对象方法
//      如果声明的是类方法，那么就必须实现类方法

/*
 类方法和对象方法的区别
 1. 对象方法以 - 开头
 类方法以 ＋ 开头
 
 2. 对象方法必须用对象调用   类方法必须用类调用
 
 3. 对象方法中可以直接访问属性(成员变量)
 类方法中不可以直接访问属性(成员变量)
 
 4. 类方法的优点，调用类方法可以效率会比调用对象方法高
 
 5. 类方法和对象方法可以进行相互调用
 5.1 对象方法中可以直接调用类方法
 5.2 类方法中间接调用对象方法 （注意：建议不这样使用）
 5.3 类方法中可以直接调用其他类方法
 5.4 对象方法中可以直接调用对象方法
 
 类方法的应用场景
 如果方法中没有使用属性（成员变量），那么能使用类方法就用类方法
 类方法的执行效率比对象方法高
 
 类方法一般用于定义工具方法
 字符串查找
 文件操作
 数据库操作
 */

+ (int)sumWithValue1:(int)value1 value2:(int)value2
{
    IPhone * p = [IPhone new];
    [p call:1300525003]; // 注意：在企业开发中，不建议这样使用
    
    return value1 + value2;
}

+ (void)test
{
    
    NSLog(@"测试结果为：%i",[IPhone sumWithValue1:90 value2:20]);
    NSLog(@"test");
}

@end

int main(int argc, const char * argv[]) {
    
    // 通过类创建对象
    // 每次给IPhone类发送一个new消息都会开辟一块新的存储空间
    // 也就意味着每次发送new消息创建出来的对象都是一个新的对象
    IPhone * p = [IPhone new];
    // 修改对象的属性
    p->_size = 3.5;
    p->_cpu = 2;
    p->_model = 5;
    p->_color = KIColorWhith;
    
        NSLog(@"size = %f, cpu = %i, model = %f, color = %i\n",p->_size,p->_cpu,p->_model,p->_color);
    
    
    // 如果给对象发消息(如果调用对象的方法)
    // [类名／对象 消息名称（方法名称）]
    [p about];
//
//    // [对象 消息名称（方法名称）]
//    // 注意：OC中的NSLog对C语言的字符串支持不是很好，如果返回的是中文的C语言字符串可能输出的是乱码，也可能什么都不输出
//    char * message = [p loadMessage];
//    
//    NSLog(@"短信为：%s\n",message);
//    
//    // 打电话
//    [p call:130052500];
//    
//    // 发短信
//    [p sendMessage:1300525003 :"NO.1"];
//    
//    [p sendMessageWithNumber:1300525003 content:"NO.2"];
//    
//    
//    //    int result = [p sumValue1:10 value2:20];
//    //
//    //    NSLog(@"两数相加的结果等于 result ＝ %i",result);
//    
//    int res = [IPhone sumWithValue1:30 value2:30];
//    NSLog(@"两数相加的结果等于 result ＝ %i",res);
//    
//    [IPhone test];
    
    return 0;
}



void test()
{
    // 1. 创建一个对象
    //    IPhone * p1 = [IPhone new];
    /*
     开辟一块存储空间
     */
    // 2.利用对象调用加法运算方法
    //    int result  = [p1 sumValue1:50 value2:50];
    int result = [IPhone sumWithValue1:50 value2:50];
    NSLog(@"两数相加的结果等于 result ＝ %i",result);
}
